
import * as entities from '@sker/entities';
import { existsSync } from 'fs';
import { join } from 'path';
import { DependencyContainer } from 'tsyringe';
import { DataSource, DataSourceOptions } from 'typeorm';
let ds: DataSource | undefined = undefined;
export const useDataSource = async (entities: any[], injector: DependencyContainer, synchronize: boolean = false) => {
    const root = injector.resolve<string>(`ROOT`)
    const env = injector.resolve<any>('ENV')
    const jsonFile = join(`${root}`, 'data/plugins', `@sker/orm.json`)
    let config: any = {
        url: env.DATABASE_URL,
        type: 'postgres'
    };
    if (existsSync(jsonFile)) {
        const data = require(jsonFile)
        if (data.url) {
            config.url = data.url;
        }
    }
    console.log(config.url)
    const url = new URL(config.url)
    const cfg: DataSourceOptions = {
        type: config.type || 'postgres',
        pool: {
            max: 100,
            min: 1
        },
        username: url.username,
        password: url.password,
        host: url.hostname,
        port: parseInt(url.port),
        database: url.pathname.replace('/', ''),
        synchronize: synchronize,
        entities: entities,
        logging: ['error'],
        logger: 'advanced-console',
        loggerLevel: 'info',
        debug: !!env.dev,
        trace: !!env.dev,
        extra: {
            connectionLimit: 100
        }
    }
    const ds = new DataSource(cfg);
    await ds.initialize();
    return ds;
}
export const createDataSource = async (injector: DependencyContainer) => {
    if (ds) return ds;
    const root = injector.resolve<string>(`ROOT`)
    const env = injector.resolve<any>('ENV')
    const jsonFile = join(`${root}`, 'data/plugins', `@sker/orm.json`)
    let config: any = {
        url: env.DATABASE_URL,
        type: 'postgres'
    };
    if (existsSync(jsonFile)) {
        const data = require(jsonFile)
        if (data.url) {
            config.url = data.url;
        }
    }
    const url = new URL(config.url)
    const cfg: DataSourceOptions = {
        type: config.type || 'postgres',
        pool: {
            max: 100,
            min: 1
        },
        username: url.username,
        password: url.password,
        host: url.hostname,
        port: parseInt(url.port),
        database: url.pathname.replace('/', ''),
        synchronize: !!env.orm,
        entities: entities,
        logging: ['error'],
        logger: 'advanced-console',
        loggerLevel: 'info',
        debug: !!env.dev,
        trace: !!env.dev,
        extra: {
            connectionLimit: 10
        }
    }
    ds = new DataSource(cfg);
    await ds.initialize();
    return ds;
}
export const useOrm = async <T>(injector: DependencyContainer, callback: (ds: DataSource) => Promise<T>) => {
    const ds = await createDataSource(injector)
    if (!ds.isInitialized) {
        await ds.initialize();
    }
    const res = await callback(ds)
    return res;
}
export const test = async (injector: DependencyContainer) => {
    const now = Date.now()
    await useOrm<any[]>(injector, async ds => {
        return ds.query(`select table_name from information_schema.tables where table_type = 'BASE TABLE' and table_schema NOT IN ('pg_catalog','information_schema')`)
    });
    return { success: true, message: 'ok', data: `${(Date.now() - now) / 1000}s` };
}
export default useOrm;
